﻿/********************************************************************************/
/* 	state.d																		*/
/*------------------------------------------------------------------------------*/
/*	製作		（　゜ワ゜）ノ　／　松久貫太									*/
/*	製作開始　	2007/05/11														*/
/*	MAIL		omega@personal.email.ne.jp										*/
/*	URL		http://nagoya.cool.ne.jp/o_mega										*/
/*																				*/
/*	このソースは「やらわかライセンス」の元で配布されています。					*/
/*-更新履歴---------------------------------------------------------------------*/
/*	2007/--/--																	*/
/*-その他-----------------------------------------------------------------------*/
/*	なし																		*/
/********************************************************************************/

/* ライブラリのインポート *******************************************************/
private import hell2;		// dHell2ライブラリ
private import screen;
private import player;
private import shot;
private import enemy;
private import vector;
private import effect;
private import keypad;
private import actor;
private import stage;

private import std.string;
private import std.math;
private import std.math2;
private import std.stream;
private import std.thread;

private import defines;

/* グローバル定数定義 ***********************************************************/
GameState g_gamestate = null;


/* load *************************************************************************/
/*	リソースの読み込み															*/
/*-引数-------------------------------------------------------------------------*/
/*	なし																		*/
/*-返り値-----------------------------------------------------------------------*/
/*	なし																		*/
/********************************************************************************/
void load()
{
	Hell_loadTexture("font","resource/font/font.bmp" , [255,255,255]);
	Hell_loadTexture("player","resource/image/player.bmp",[-2,0,0]);
	Hell_loadTexture("title","resource/image/title.bmp",[-2,0,0]);
	
	Hell_write("resource loaded.\n");
}

/* GameState ********************************************************************/
/*	ゲーム全体の状態遷移を管理するクラス										*/
/********************************************************************************/
class GameState
{
private:
	int msg;				// リクエストメッセージ
public:
	enum
	{
		MSG_NONE,
		MSG_REQ_TITLE,			// タイトル状態へ　行きたい
		MSG_REQ_GAME,			// ゲーム
	}
	
	void move(){}
	void draw(){}
	
	// 設定
	void setMsg(int m)
	{
		msg = m;
	}
	// 取得
	int getMsg()
	{
		return msg;
	}
}



void loop()
{
	if(g_gamestate)
	{
		// メッセージ指示による状態遷移
		switch(g_gamestate.msg)
		{
			case GameState.MSG_NONE:
				break;
			case GameState.MSG_REQ_TITLE:
				g_gamestate = new TitleMain();
				break;
			case GameState.MSG_REQ_GAME:
				g_gamestate = new GameMain();
				break;
			default:
				Hell_write("Uknown msg at loop.");
		}
	}
	else
	{
		// 初期状態
		g_gamestate = new GameMain();
		Hell_write("Exec loop.\n");
	}
	
	g_gamestate.move();
	g_gamestate.draw();
}

/* TitleMain ********************************************************************/
/*	タイトルの状態																*/
/********************************************************************************/
class TitleMain : GameState
{
public:
	int timer;
	Vec3 mouse;
	Keypad keypad;
	
	this()
	{
		timer = 0;
		mouse = new Vec3();
		keypad = new Keypad(0);
	}
	
	void move()
	{
		timer++;
		Vec3 cursor = new Vec3();
		cursor.x = (Hell_getMouseX() - 320) / 320.0 * CHAR_X_ABSMAX;
		cursor.y = (Hell_getMouseY() - 240) / 240.0 * CHAR_Y_ABSMAX;
		mouse.x = mouse.x * 0.9 + cursor.x * 0.1;
		mouse.y = mouse.y * 0.9 + cursor.y * 0.1;
		
		if( keypad.isPushEnter() ) setMsg(GameState.MSG_REQ_GAME);
	}
	
	void draw()
	{
		//Hell_begin();
		resetPerspective();
		Hell_setAlpha(HELL_ALPHA_PRODUCT);
		Hell_drawRect(0,0,getScreenWidth(),getScreenHeight(), 0, 0, 128,160,240,255);
		
		Hell_setAlpha(HELL_ALPHA_NORMAL);
		setPerspective();
		glLoadIdentity();
		
		glTranslatef(0 , 0 , CHAR_Z_SURFACE);
		glRotatef(mouse.y / CHAR_Y_ABSMAX * 10 , -mouse.x / CHAR_X_ABSMAX * 10 , 0);
		glTranslatef(0 , 0 , -CHAR_Z_SURFACE);
		
		for(int t=0;t<60;t+=10){
			glPushMatrix();
			{
				int tt = (timer / 2 + t) % 60;
				glTranslatef(0,0, CHAR_Z_SURFACE);
				glScalef(40.0 + tt * 2 , 40.0 + tt * 2 , 40.0 + tt * 2);
				glColor4f(1 , 1 , 1 , 0.2 - tt / 60.0);
				drawBillBoard("title" , 0 , 0 , 320 , 480);
			}
			glPopMatrix();
		}
		glPushMatrix();
		{
			glTranslatef(0,0, CHAR_Z_SURFACE);
			glScalef(40.0 , 40.0  , 40.0);
			glColor4f(1 , 1 , 1 , 0.5);
			drawBillBoard("title" , 0 , 0 , 320 , 480);
		}
		glPopMatrix();
		
		resetPerspective();
		
		Hell_drawFont("Yaruhala / OMEGA 2007" , 140, 480-48 , 2 , 160,160,160);
		
		if(timer % 60 < 50)
		{
			int xx = 0,yy = 0;
			if(timer % 120 < 10){
				xx = Hell_randInt(-4,4);
				yy = Hell_randInt(-4,4);
			}
			Hell_drawFont("Click to start!",200 + xx , 240 + 24 + yy ,2 );
		}
	}
}

/* GameMain *********************************************************************/
/*	ゲーム本体の状態															*/
/********************************************************************************/
class GameMain : GameState
{
public:
	Player player = null;
	ShotActor shotactor = null;
	EnemyActor enemyactor = null;
	EffectActor effectactor = null;
	PerticleActor perticleactor = null;
	Stage stage = null;
	Keypad keypad;
	
	int timer;
	
	this()
	{
		player = new Player(this);
		shotactor = new ShotActor(this,64);
		enemyactor = new EnemyActor(this,512);
		effectactor = new EffectActor(384);
		perticleactor = new PerticleActor(4096);
		stage = new Stage(this);
		keypad = new Keypad(0);
		timer = 0;
	}
	
	void move()
	{
		if(player.exist)
		{
			timer++;
			player.move();
		}
		else
		{
			
			if(keypad.isPushEnter())
			{
				setMsg(GameState.MSG_REQ_TITLE);
			}
		}
		
		shotactor.move();
		effectactor.move();
		perticleactor.move();
		enemyactor.move();
		stage.move();
	}
	
	void draw()
	{
		//Hell_begin();
		resetPerspective();
		stage.drawBlur();
		//Hell_setAlpha(HELL_ALPHA_PRODUCT);
		//Hell_drawRect(0,0,640,480, 0, 0, 128,160,240,255);
		
		Hell_setAlpha(HELL_ALPHA_NORMAL);
		setPerspective();
		
		// 視点ぐりぐり
		glLoadIdentity();
		glTranslatef(player.position.x , player.position.y , CHAR_Z_SURFACE);
		glRotatef(player.position.y / CHAR_Y_ABSMAX * 3, -player.position.x / CHAR_X_ABSMAX * 3, 0);
		glTranslatef(-player.position.x , -player.position.y , -CHAR_Z_SURFACE);
		
		stage.drawBack();
		
//		player.drawMarker();
		enemyactor.draw();
		shotactor.draw();
		
		Hell_setAlpha(HELL_ALPHA_ADD);
		resetCullFace();
		effectactor.draw();
		perticleactor.draw();
		Hell_setAlpha(HELL_ALPHA_NORMAL);
		
		player.drawPlayer();
		
		resetPerspective();
		player.drawStatus();
		
		stage.draw();
		
		Hell_drawFont("TIMER:" ~ std.string.toString(cast(double)(timer / 6) / 10) ,0 ,0 , 2);
		Hell_drawFont("SHOT:" ~ std.string.toString(shotactor.countExist()) ,0 ,16 , 2);
		Hell_drawFont("ENEM:" ~ std.string.toString(enemyactor.countExist()) ,0 ,32 , 2);
		Hell_drawFont("EFCT:" ~ std.string.toString(effectactor.countExist()) ,0 ,48 , 2);
		Hell_drawFont("PRTC:" ~ std.string.toString(perticleactor.countExist()) ,0 ,64 , 2);
		Hell_drawFPS();
	}
	
	void addEffect(Vec3 p ,Vec3 v,EFFECTTYPE type){
		if(type == EFFECTTYPE.POINT){
			perticleactor.add(p,v,type);
		}else{
			effectactor.add(p,v,type);
		}
	}
}
